home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Tech Arsenal 1
/
Tech Arsenal (Arsenal Computer).ISO
/
tek-04
/
vballs11.zip
/
BALLS2.C
< prev
next >
Wrap
C/C++ Source or Header
|
1991-03-06
|
5KB
|
277 lines
/*
* balls2.c - Attempt to draw balls in VGA256 mode
*
* Uses BGI interface
*
* Adapted by: Scott J. Walter (GEnie: S.Walter4)
*
*/
/* INCLUDES */
#include <stdio.h>
#include <dos.h>
#include <math.h>
#include <graphics.h>
#include <stdlib.h>
#include <conio.h>
#include <alloc.h>
#include <bios.h>
#include <time.h>
/* DEFINES */
#define DIM 3 /* number of dimensions */
#define TRUE 1
#define FALSE 0
typedef unsigned char UBYTE;
typedef double VECTOR [DIM];
typedef struct {
UBYTE Rvalue;
UBYTE Gvalue;
UBYTE Bvalue;
} ColorValue;
/* PROTOTYPES */
int huge DetectVGA256(void);
void VGASetAllPalette(UBYTE far *pal);
void Hsi2Rgb(float H, float S, float I, ColorValue *C);
void normalize (VECTOR this_vec);
double dot_prod (VECTOR vec1, VECTOR vec2);
void put_atom(int R, int index, int xc, int yc, VECTOR l_source);
void put_atom(int R, int index, int xc, int yc, VECTOR l_source)
{
VECTOR s_point;
int R2, color = 0;
double x,y,z,r,intensity;
normalize(l_source); /* normalize the light source */
R2=R*R; /* only calculate R*R once */
for (x=-R;x<=+R;x=x+1) /* scan an area 2R x 2R */
{
for (y=-R;y<=+R;y=y+1)
{
r=(x*x)+(y*y); /* check that the pixel is within a */
if (r <= R2) /* circle of radius R */
{
z=sqrt((R2)-r); /* calculate the altitude of the point */
s_point[0]= x; /* set the normal surface vector to the */
s_point[1]= y; /* coordinates of the point */
s_point[2]= z;
intensity = random(100);
intensity /= 100;
intensity += 64 * dot_prod(s_point,l_source)/R;
color = (int)intensity;
color = color<0 ? 0 : (color> 63 ? 63 : color);
putpixel(x+xc,y+yc,index*64 + color);
}
}
}
}
/*
* Normalize a vector to unit magnitude. Calculate the magnitude as:
*
* magnitude = sqrt ( x^2 + y^2 + z^2 )
*
* Normalize the vector by dividing each coordinate by the magnitude.
* FOR loops are used to maintain generality--any dimension vector may
* be normalized by changing DIM.
*/
void normalize (VECTOR this_vec)
{
double mag;
int count;
mag = 0.0;
for (count = 0; count < DIM; count++)
mag = mag + (this_vec [count] * this_vec [count]);
mag = sqrt(mag);
for (count = 0; count < DIM; count++)
this_vec [count] = this_vec [count]/mag;
}
/* Calculate the cosine of the angle between two vectors.
*
* dot product = (x1 * x2) + (y1 * y2) + (z1 * z2)
*/
double dot_prod (VECTOR vec1, VECTOR vec2)
{
double COSINE;
int count;
COSINE = 0.0;
for (count = 0; count < DIM; count++)
COSINE += vec1 [count] * vec2 [count];
return (COSINE);
}
void VGASetAllPalette(pal)
UBYTE far *pal;
{
struct REGPACK r;
r.r_ax = 0x1012;
r.r_bx = 0x0000;
r.r_cx = 0x0100;
r.r_es = FP_SEG(pal);
r.r_dx = FP_OFF(pal);
intr(0x10, &r);
}
void Hsi2Rgb(float H, float S, float I, ColorValue *C)
{
float T, Rv, Gv, Bv;
float Pi = 3.14159265358979;
if(H<0.0)
H = 1.0 + H;
if(H>1.0)
H = H - 1.0;
T = 2.0 * Pi * H;
Rv = 1 + S * sin(T - 2 * Pi / 3);
Gv = 1 + S * sin(T);
Bv = 1 + S * sin(T + 2 * Pi / 3);
T = 63.999 * I / 2;
C->Rvalue = (UBYTE)(Rv * T);
C->Gvalue = (UBYTE)(Gv * T);
C->Bvalue = (UBYTE)(Bv * T);
}
int huge DetectVGA256()
{
int gdriver, gmode;
detectgraph(&gdriver, &gmode);
if((gdriver==VGA)||(gdriver==MCGA))
return 0; /* Default video mode = 0 */
else
return grError; /* Couldn't detect hardware */
}
/* MAIN */
void main()
{
int Y, Z, ErrorCode, Driver = DETECT, Mode;
int radius = 40;
VECTOR light = { -2.0, -2.0, 3.0 }; /* light source from upper left */
UBYTE far *pal;
float off, hue;
ColorValue C;
installuserdriver("VGA256", DetectVGA256);
initgraph(&Driver, &Mode, "");
ErrorCode = graphresult();
if(ErrorCode!=grOk)
{
printf("Error: %s\n", grapherrormsg(ErrorCode));
exit(1);
}
randomize();
pal = (UBYTE far *)farmalloc(768);
for(Y=0;Y<5;Y++)
for(Z=0;Z<64;Z++)
{
Hsi2Rgb(0.25+(float)Y/5.0, 1.0, (float)Z/64.0, &C);
*(pal+Y*192+Z*3+0) = C.Rvalue;
*(pal+Y*192+Z*3+1) = C.Gvalue;
*(pal+Y*192+Z*3+2) = C.Bvalue;
}
VGASetAllPalette(pal);
for(Y=0;Y<2;Y++)
for(Z=0;Z<2;Z++)
put_atom(radius, Y*2+Z, 80+160*Z, 50+100*Y, light);
off = 0.30;
do
{
for(Y=0;Y<5;Y++)
for(Z=0;Z<64;Z++)
{
hue = off+(float)Y/5.0;
if(hue>1.0)
hue = hue - 1.0;
Hsi2Rgb(hue, 1.0, (float)Z/64.0, &C);
*(pal+Y*192+Z*3+0) = C.Rvalue;
*(pal+Y*192+Z*3+1) = C.Gvalue;
*(pal+Y*192+Z*3+2) = C.Bvalue;
}
VGASetAllPalette(pal);
off += 0.05;
if(off>1.0)
off = off - 1.0;
} while(!bioskey(1));
getch();
farfree((void far *)pal);
closegraph();
}